package com.woniuxy.special.websocket;

import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONUtil;
import com.woniuxy.special.dto.WebSocketMessageDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * websocket的消息处理器
 */
@Component
public class MessageHandler implements WebSocketHandler {
    private static final Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap();
    @Autowired
    private StringRedisTemplate template;

    /**
     * 客户端和服务器建立连接
     *
     * @param webSocketSession
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        //获取登录用户ID
        String loginUserId = Objects.requireNonNull(webSocketSession.getUri()).toString().split("=")[1];
        //将登录用户ID存入session
        webSocketSession.getAttributes().put("loginUserId", loginUserId);
        //将连接对象存入map
        sessionMap.put(loginUserId, webSocketSession);
    }

    /**
     * 服务端收到客户端发来的消息
     *
     * @param webSocketSession
     * @param webSocketMessage
     * @throws Exception
     */
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
        System.out.println(webSocketMessage);
        System.out.println(webSocketSession);
        WebSocketMessageDto bean = JSONUtil.toBean(webSocketMessage.getPayload().toString(), WebSocketMessageDto.class);
        //设置时间
        bean.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()));
        //将消息转发给接收用户
        WebSocketSession socketSessionTo = sessionMap.get(bean.getTo());
        if (socketSessionTo != null && socketSessionTo.isOpen()) {
            //用户在线状态发送
            socketSessionTo.sendMessage(new TextMessage(JSONUtil.toJsonStr(bean)));
        }
        //将发送内容存入redis
        String keyFrom = "sendMessage:from:to:day:" + bean.getFrom() + ":" + bean.getTo() + ":" + new SimpleDateFormat("yyyy-MM-dd").format(new Date().getTime());
        template.opsForZSet().add(keyFrom, JSONUtil.toJsonStr(bean), DateTime.now().getTime());
        template.expire(keyFrom, 30, TimeUnit.DAYS);
        String keyTo = "sendMessage:to:from:day:" + bean.getTo() + ":" + bean.getFrom() + ":" + new SimpleDateFormat("yyyy-MM-dd").format(new Date().getTime());
        template.opsForZSet().add(keyTo, JSONUtil.toJsonStr(bean), System.currentTimeMillis());
        template.expire(keyTo, 30, TimeUnit.DAYS);
    }

    /**
     * 连接异常时执行
     *
     * @param webSocketSession
     * @param throwable
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
    }

    /**
     * 连接关闭
     *
     * @param webSocketSession
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        sessionMap.remove(webSocketSession.getAttributes().get("loginUserId"));
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}
